package com.aiwu.dialog

import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import androidx.annotation.StringRes
import com.aiwu.ScreenEditActivity
import com.aiwu.bean.ScreenConfig
import com.aiwu.library.App
import com.aiwu.library.abs.ui.adapter.BaseMultiFocusAdapter
import com.aiwu.library.ui.pop.EditDialog
import com.aiwu.library.ui.widget.layoutmanager.FocusFixedLinearLayoutManager
import com.aiwu.library.util.ActivityMessenger
import com.aiwu.library.util.DialogUtil
import com.aiwu.library.util.DisplayUtil
import com.aiwu.library.util.ToastUtil
import com.aiwu.utils.PrefsHelper
import com.aiwu.utils.saveValue
import com.aiwu.utils.saveValueAsBoolean
import com.chad.library.adapter.base.BaseViewHolder
import org.citra.citra_emu.NativeLibrary
import org.citra.citra_emu.R
import org.citra.citra_emu.activities.EmulationActivity
import org.citra.citra_emu.databinding.DialogScreenLayoutListBinding
import org.citra.citra_emu.display.ScreenLayout
import org.citra.citra_emu.features.settings.model.IntSetting
import org.citra.citra_emu.utils.EmulationMenuSettings

/**
 * 屏幕布局
 */
class SwitchScreenLayoutDialog(
    context: Context,
    private val emulationActivity: EmulationActivity,
) : AlertDialog(context, R.style.AiWuDialog), ActivityMessenger.OnActivityResultCallBack {
    companion object {

        /**
         * 获取屏幕布局配置列表
         * @param isLandscape 是否横屏
         */
        fun getScreenLayoutConfigList(isLandscape: Boolean = DisplayUtil.isLandscape()): List<ScreenConfig> {
            //横屏的系统配置
            val landscapeSystemConfigList = arrayListOf(
                R.string.emulation_screen_layout_landscape to ScreenLayout.MOBILE_LANDSCAPE,
                R.string.emulation_screen_layout_portrait to ScreenLayout.MOBILE_PORTRAIT,
                R.string.emulation_screen_layout_single to ScreenLayout.SINGLE_SCREEN,
                R.string.emulation_screen_layout_sidebyside to ScreenLayout.SIDE_SCREEN,
                R.string.emulation_screen_layout_hybrid to ScreenLayout.HYBRID_SCREEN,
            )
            //竖屏的系统配置
            val portraitSystemConfig =
                R.string.emulation_screen_layout_landscape to ScreenLayout.DEFAULT
            return arrayListOf<ScreenConfig>().apply {
                val startId: Int
                val endId: Int
                if (isLandscape) {
                    //横屏要加上4个配置
                    landscapeSystemConfigList.forEach {
                        add(
                            createSystemConfigByType(
                                App.getContext().getString(it.first),
                                it.second.int
                            )
                        )
                    }
                    startId = PrefsHelper.SCREEN_CONFIG_ID_LANDSCAPE_START
                    endId = PrefsHelper.SCREEN_CONFIG_ID_LANDSCAPE_END
                } else {
                    //竖屏要加上1个配置
                    val config: ScreenConfig = createSystemConfigByType(
                        App.getContext().getString(portraitSystemConfig.first),
                        portraitSystemConfig.second.int
                    )
                    add(config)
                    startId = PrefsHelper.SCREEN_CONFIG_ID_PORTRAIT_START
                    endId = PrefsHelper.SCREEN_CONFIG_ID_PORTRAIT_END
                }
                for (i in startId..endId) {
                    PrefsHelper.instance.getScreenConfig(i)?.let {
                        add(it)
                    }
                }
            }
        }

        /**
         * 构建系统的几个配置
         */
        private fun createSystemConfigByType(name: String, layoutOptionType: Int): ScreenConfig {
            return ScreenConfig(
                false, layoutOptionType == PrefsHelper.instance.getLastScreenConfigId(),
                layoutOptionType,
                name
            )
        }

        /**
         * 切换到系统的屏幕布局
         */
        fun changeToSystemScreenLayout(screenLayoutId: Int, rotation: Int) {
            IntSetting.CUSTOM_LAYOUT.saveValueAsBoolean(false)
            EmulationMenuSettings.landscapeScreenLayout = screenLayoutId
            IntSetting.SCREEN_LAYOUT.saveValue(screenLayoutId)
            NativeLibrary.reloadSettings()
            NativeLibrary.notifyOrientationChange(screenLayoutId, rotation)
        }

        /**
         * 切换到自定义的屏幕布局
         */
        fun changeToCustomScreenLayout(config: ScreenConfig, rotation: Int) {
            IntSetting.CUSTOM_LAYOUT.saveValueAsBoolean(true)
            val values = intArrayOf(
                config.topLeft, config.topTop, config.topRight, config.topBottom,
                config.bottomLeft, config.bottomTop, config.bottomRight, config.bottomBottom
            )
            arrayOf(
                IntSetting.CUSTOM_TOP_LEFT,
                IntSetting.CUSTOM_TOP_TOP,
                IntSetting.CUSTOM_TOP_RIGHT,
                IntSetting.CUSTOM_TOP_BOTTOM,
                IntSetting.CUSTOM_BOTTOM_LEFT,
                IntSetting.CUSTOM_BOTTOM_TOP,
                IntSetting.CUSTOM_BOTTOM_RIGHT,
                IntSetting.CUSTOM_BOTTOM_BOTTOM,
            ).forEachIndexed { index, intSetting ->
                intSetting.saveValue(values[index])
            }
            NativeLibrary.reloadSettings()
            NativeLibrary.notifyOrientationChange(
                ScreenLayout.DEFAULT.int,
                rotation
            )
        }
    }

    private val binding = DialogScreenLayoutListBinding.inflate(LayoutInflater.from(context))

    private val configAdapter by lazy {
        ScreenLayoutAdapter()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        setCancelable(true)
        setCanceledOnTouchOutside(true)
        initView()
        refreshData()
    }

    private fun initView() {
        binding.run {
            tvInsert.setOnClickListener {
                insertConfig()
            }
            rv.run {
                itemAnimator = null
                setLayoutManager(
                    FocusFixedLinearLayoutManager(context)
                        .setInterceptNonMainOrientationOutEvent(true)
                )
                adapter = configAdapter.apply {
                    setOnItemChildClickListener { _, view, position ->
                        configAdapter.getItem(position)?.let {
                            when (view.id) {
                                R.id.layout_name -> {
                                    showRenameDialog(it, position)
                                }

                                R.id.btn_use -> {
                                    resolveUseConfig(it)
                                }

                                R.id.btn_edit -> {
                                    ScreenEditActivity.launch(
                                        emulationActivity,
                                        it.id,
                                        false,
                                        this@SwitchScreenLayoutDialog
                                    )
                                }

                                R.id.btn_copy -> {
                                    copyConfig(it)
                                }

                                R.id.btn_delete -> {
                                    showDeleteDialog(it.id, position)
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private fun refreshData() {
        configAdapter.setNewData(getScreenLayoutConfigList())
    }

    /**
     * 使用某个配置
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun resolveUseConfig(item: ScreenConfig) {
        PrefsHelper.instance.setLastScreenConfigId(item.id)
        if (DisplayUtil.isLandscape()) {
            PrefsHelper.instance.setLastLandscapeScreenConfigId(item.id)
        } else {
            PrefsHelper.instance.setLastPortraitScreenConfigId(item.id)
        }
        val rotation = emulationActivity.windowManager.defaultDisplay.rotation
        if (item.isCustom) {
            changeToCustomScreenLayout(item, rotation)
        } else {
            changeToSystemScreenLayout(item.id, rotation)
        }
        for (itemBean in configAdapter.data) {
            itemBean.isUsing = itemBean.id == item.id
        }
        configAdapter.notifyDataSetChanged()
    }

    /**
     * 获取新建的配置id
     * @return null表示位置满了
     */
    private fun getNewConfigId(): Int? {
        val startId: Int
        val endId: Int
        if (DisplayUtil.isLandscape()) {
            startId = PrefsHelper.SCREEN_CONFIG_ID_LANDSCAPE_START
            endId = PrefsHelper.SCREEN_CONFIG_ID_LANDSCAPE_END
        } else {
            startId = PrefsHelper.SCREEN_CONFIG_ID_PORTRAIT_START
            endId = PrefsHelper.SCREEN_CONFIG_ID_PORTRAIT_END
        }
        for (i in startId..endId) {
            var repeat = false
            for (item in configAdapter.data) {
                if (item.id == i) {
                    repeat = true
                    break
                }
            }
            if (!repeat) {
                return i
            }
        }
        return null
    }

    /**
     * 添加新配置
     */
    private fun insertConfig() {
        //找到新配置的id
        val newConfigId = getNewConfigId()
        if (newConfigId == null) {
            ToastUtil.toast("配置已满,新建配置失败")
            return
        }
        ScreenEditActivity.launch(emulationActivity, newConfigId, true, this)
    }

    /**
     * 复制配置
     *
     * @return 是否复制成功
     */
    private fun copyConfig(itemBean: ScreenConfig): Boolean {
        val newConfigId = getNewConfigId()
        if (newConfigId == null) {
            ToastUtil.toast("配置已满,复制配置失败")
            return false
        }
        val newConfig = ScreenConfig(
            isCustom = true,
            isUsing = false,
            id = newConfigId,
            name = itemBean.name + "-副本",
            topLeft = itemBean.topLeft,
            topTop = itemBean.topTop,
            topRight = itemBean.topRight,
            topBottom = itemBean.topBottom,
            bottomLeft = itemBean.bottomLeft,
            bottomTop = itemBean.bottomTop,
            bottomRight = itemBean.bottomRight,
            bottomBottom = itemBean.bottomBottom
        )
        //添加新配置
        PrefsHelper.instance.saveNewScreenConfig(
            newConfigId, newConfig.name,
            newConfig.topLeft, newConfig.topTop, newConfig.topRight, newConfig.topBottom,
            newConfig.bottomLeft, newConfig.bottomTop, newConfig.bottomRight, newConfig.bottomBottom
        )
        configAdapter.addData(newConfig)
        binding.rv.smoothScrollToPosition(configAdapter.itemCount - 1)
        return true
    }

    /**
     * 修改名称的弹窗
     */
    private fun showRenameDialog(item: ScreenConfig, position: Int) {
        object : EditDialog(context) {
            override fun initView() {
                val tvTitle = findViewById<TextView>(R.id.tv_title)
                tvTitle.setText(R.string.emu_lib_rename_config_name)
                val et = findViewById<EditText>(R.id.et)
                et.setText(item.name)
                et.setSelection(item.name.length)
                et.setHint(R.string.emu_lib_input_config_name)
                val btnCancel = findViewById<TextView>(R.id.btn_cancel)
                val btnConfirm = findViewById<TextView>(R.id.btn_confirm)
                btnCancel.setOnClickListener { dismiss() }
                btnConfirm.setOnClickListener {
                    val newName = et.getText().toString()
                    if (TextUtils.isEmpty(newName)) {
                        ToastUtil.toast(R.string.emu_lib_config_name_empty)
                        return@setOnClickListener
                    }
                    dismiss()
                    PrefsHelper.instance.editScreenConfigName(item.id, newName)
                    item.name = newName
                    configAdapter.notifyItemChanged(position)
                }
            }
        }.show()
    }

    /**
     * 删除的弹窗
     */
    private fun showDeleteDialog(id: Int, position: Int) {
        DialogUtil.showTip(context, R.string.emu_lib_delete_config_tip, {
            configAdapter.remove(position)
            PrefsHelper.instance.removeScreenConfig(id)
        }, null)
    }

    override fun onActivityResult(resultCode: Int, result: Intent?) {
        if (resultCode != Activity.RESULT_OK) {
            return
        }
        result?.let {
            val action = it.getIntExtra(
                ScreenEditActivity.RESULT_ACTION,
                ScreenEditActivity.RESULT_INSERTED
            )
            val layoutId = it.getIntExtra(ScreenEditActivity.RESULT_ID, -1)
            if (layoutId == -1) {
                return
            }
            if (action == ScreenEditActivity.RESULT_INSERTED) {
                onLayoutInserted(layoutId)
            } else {
                onLayoutEdited(layoutId)
            }
        }
    }

    /**
     * 新建了布局
     */
    private fun onLayoutInserted(screenLayoutId: Int) {
        PrefsHelper.instance.getScreenConfig(screenLayoutId)?.let {
            configAdapter.addData(it)
            binding.rv.smoothScrollToPosition(configAdapter.itemCount - 1)
            resolveUseConfig(it)
        }
    }

    /**
     * 编辑了布局
     */
    private fun onLayoutEdited(screenLayoutId: Int) {
        PrefsHelper.instance.getScreenConfig(screenLayoutId)?.let {
            resolveUseConfig(it)
        }
    }

    override fun show() {
        super.show()
        DialogUtil.setDialog(this, 0.6f, 0.85f, 0.85f, 0.6f)
    }

    private fun getString(@StringRes resId: Int): String {
        return context.getString(resId)
    }

    private class ScreenLayoutAdapter : BaseMultiFocusAdapter<ScreenConfig, BaseViewHolder>(
        R.layout.emu_lib_item_operate_config,
        null
    ) {
        override fun getItemView(layoutResId: Int, parent: ViewGroup): View {
            val itemView = super.getItemView(layoutResId, parent)
            itemView.setPadding(0, 0, 0, 0)
            return itemView
        }

        override fun convert(helper: BaseViewHolder, item: ScreenConfig) {
            val isCustom: Boolean = item.isCustom
            helper.setText(R.id.tv_name, item.name)
                .setGone(R.id.iv_edit, isCustom)
                .setEnabled(R.id.layout_name, isCustom)
                .setText(
                    R.id.btn_use,
                    if (item.isUsing) R.string.emu_lib_using else R.string.emu_lib_use
                )
                .setEnabled(R.id.btn_use, !item.isUsing)
                .setGone(R.id.btn_edit, isCustom)
                .setGone(R.id.btn_copy, isCustom)
                .setGone(R.id.btn_delete, isCustom && !item.isUsing)
                .addOnClickListener(
                    R.id.layout_name,
                    R.id.btn_use,
                    R.id.btn_edit,
                    R.id.btn_copy,
                    R.id.btn_delete
                )
        }
    }

}